import {findAllParentByCode,findLevelByCode,findNodeByCode} from './treeUtil.js'
import xID from "./xID.js";
import {replaceByObj} from "./xUtil.js";

/*
*  cfg: {
*    style,
*    placeholder,
*    title,
*    data,
*
*    valueType  绑定对象中key 对应的数据类型， code|object
*               默认是最低一级的code
*  }
* */
const splitChar=' / '
const tmplBase =`
        <div  class="{{class}}">
             <div type="head" class="xhead">
                 <input  readonly="readonly" class="xinput-icon"/> 
                  <i class="iconfont icon-dropdown after-icon-set"></i>     
             </div>
             <div type="main" class="xmain" >
                 <div type="tab" ></div>
                 <table><tbody type ="body"></tbody></table>
                 <div type="footer">
                      <button type ="clear" class="btn btn-sm btn-secondary">清除</button>                         
                      <button type ="ok" class="btn btn-sm btn-primary"> 确认 </button>	               
                 </div>
             </div>
        </div>`;

const tmplActive = 'class="active"'
const tmplTag = '<label type="tag">{{tag}}</label>'
const tmplTr = '<tr>{{trHtml}}</tr>'
const tmplTd = '<td><div type="cell">{{tdHtml}}</div></td>'
const cascadeItem = '<span {{active}} data-code="{{code}}" type="item">{{name}}</span>'
const cascadeTabItem ='<span {{active}} type="tab-item">{{name}}</span>'
const tmplTitle = `title="{{title}}"`;


export default class xCascade {
	
    /* 定义变量 开始*/
    vCfg;
    $root;
    $container;
    $head;
    $main;
    $tab;
    $body;
    $input;
    vActiveLevel;
    vMaxLevel;
    //绑定事件和 xBind 联动用
    vBindEvent;
    vTmpEvent ={};
    vSelect=[];
    vClickId = 'click.'+xID.getID();

    /* 定义变量 结束*/
    // 构造函数
    constructor(cfg){
        this.vCfg =cfg;
    	if (cfg.tab){
            this.vMaxLevel = cfg.tab.length;
        }
        this.$root = $('#' + cfg.el);
        this.$root.html(tmplBase.replace('{{class}}', cfg.style ||'cascade'));
    	this.renderInit();
        if(this.vCfg.placeholder){
            this.$input.attr('placeholder',this.vCfg.placeholder);
        }
    	if(this.vCfg.active)
    	    this.initValue(this.vCfg.active);
    };

    initValue(value){
        if(value){
            let last;
            if((this.vCfg.valueType||'code' =='code'))
                last = findNodeByCode(this.vCfg.data,value);
            else
                last = value[value.length-1];
            let parents;
            if(last && this.vCfg.data && this.vCfg.data.length>0) {
                parents = findAllParentByCode(this.vCfg.data, last.code);
                //active 需要更新下
                this.vSelect = [];
                this.vSelect.push(...parents.reverse());
                this.vSelect.push(last);
            }
        }else{
            this.vSelect=[];
        }
        this.renderHead();
        this.verify();
    }

    /* 渲染区块 开始 */
    renderInit() {

        this.$head      = this.$root.find('[type="head"]');
        this.$main      = this.$root.find('[type="main"]');
        this.$tab       = this.$root.find('[type="tab"]');
        this.$body      = this.$root.find('[type="body"]');
        this.$input     = this.$root.find('input');
        this.renderHead();
        this.$main.hide();
        // event 处理 注册
        this.$head.on('click', this.evDrop.bind(this));
        this.$root.on('click', '[type="item"]', this.evClickItem.bind(this));
        this.$input.on('focus',this.evFocus.bind(this));
        this.$root.on('click', '[type="tab-item"]', this.evClickTabItem.bind(this));
        this.$root.on('click', '[type="clear"]', this.evClear.bind(this));
        this.$root.on('click', '[type="ok"]', this.evOk.bind(this));
        this.$root.on('click', this.evRootClick.bind(this));
        this.$root.on('keydown',this.evKeydown.bind(this));
        let title ='';
        if(this.vCfg.title)
            title = tmplTitle.replace("{{title}}",this.vCfg.title);
        this.$head.attr("title",title);
    };

    /*
      总共 4 个状态
        active  ,无 active
        valid,无valid ,invalid
     */
    renderStatus(action,status){
        if(action=='add'){
            this.$head.addClass(status);
        }else{
            this.$head.removeClass(status);
        }
    }

    renderTab(){
    	this.$tab.html(this.renderTabItem(this));
    };


    renderHead(){
        let names =[];
        this.vSelect.forEach(value => names.push(value.name||value.code) );
        this.$input.attr('value',names.join(splitChar)||'');
    }

    renderBody(jd) {
        let [tds,trs,tag,tagCellHtml,itemCellHtml] = ['','','','',''];
        let hasGroup = false;
        if(jd && jd[0]){
            hasGroup =jd[0].tag?true:false;
            //有分类
            if(hasGroup) {
                jd.forEach((item, index) => {
                    if(tag != item.tag) {
                        /*
                         分类不同
                         1： 如果是起始 增加一个 分类格子 ，同时 增加 一个item 格子
                         2:  如果 不是起始 ,需要重新一行 。
                         */
                        if(index > 0) {
                            tds = tagCellHtml + tmplTd.replace('{{tdHtml}}', itemCellHtml);
                            trs += tmplTr.replace('{{trHtml}}', tds);
                            tagCellHtml = '';
                            itemCellHtml = '';
                        }
                        tagCellHtml = tmplTd.replace('{{tdHtml}}', this.renderTag(item.tag));
                    }
                    itemCellHtml += this.renderItem(item);
                    tag = item.tag;
                    // 如果是最后一行
                    if(jd.length == index + 1) {
                        tds = tagCellHtml + tmplTd.replace('{{tdHtml}}', itemCellHtml);
                        trs += tmplTr.replace('{{trHtml}}', tds);
                    }
                });
                //无分类
            } else {
                jd.forEach(item => {
                    tds += this.renderItem(item);
                });
                trs = tmplTr.replace('{{trHtml}}', tmplTd.replace('{{tdHtml}}', tds));
            }
        }

        this.$body.html(trs);
    }

    renderItem(item){
        let obj ={code:item.code,name:item.name||item.code};
        //激活判断
        let codes=[];
        this.vSelect.forEach(value => codes.push(value.code));
        obj.active =  codes.includes(item.code)?tmplActive:'';
        return replaceByObj(cascadeItem,obj);
    }

    // only for cascade
    renderTabItem(){
        let s='';
        if(this.vCfg.tab){
            for(let i=0; i<this.vCfg.tab.length;i++){
                s += replaceByObj(cascadeTabItem,{name:this.vCfg.tab[i],
                    active:i+1==this.vActiveLevel?'class="active"':''});
            }
        }
        return s;
    };

    renderTag(tag){
        return tmplTag.replace('{{tag}}',tag);
    }

    /* 渲染区块 结束 */
    //    事件 入口
    evClickItem(e){
        let code = e.target.getAttribute("data-code");
        let level = findLevelByCode(this.vCfg.data,code);
        let jd = findNodeByCode(this.vCfg.data,code);
        this.vActiveLevel = level+1;
        // 点击code 是否在已经选好的数据中,不在选择中，不在 。本级替换，下级清掉
        let codes=[];
        this.vSelect.forEach(value => codes.push(value.code));
        if (!codes.includes(code)){
            this.vSelect.length = level-1;
            this.vSelect.push(jd);
        }
        //非最后一级
        if(jd.children){
            this.renderTab();
            this.renderBody(jd.children);
            this.renderHead(this);
        }else{
            this.renderHead(this);
            this.$main.hide();
        }

        if(this.vBindEvent){
            if((this.vCfg.valueType||'code') =='code' && this.vSelect && this.vSelect.length>0){
                this.vBindEvent(this.vSelect[this.vSelect.length-1].code)
            }else
                this.vBindEvent(this.vSelect);
        }
    }

    evClickTabItem(e){
        let name = e.target.innerText;
        let level = this.vCfg.tab.indexOf(name)+1;
        if(this.vActiveLevel!=level){
            this.vActiveLevel = level;
            this.renderTab();
            if (level == 1)
                this.renderBody(this.vCfg.data);
            else if(this.vSelect.length>0){
                if(this.vSelect[level-2])
                     this.renderBody(findNodeByCode(this.vCfg.data,this.vSelect[level-2].code).children);
            }
                //当前tab的 父节点 的子节点

            else
                this.renderBody();
        }
    }

    evFocus(e){
        this.evDrop(null);
    }

    evDrop(e){
        if(this.$main.is(':visible'))
            return;
        this.vActiveLevel = 1;
        this.renderStatus("add","active");
        this.renderTab();
        this.renderBody(this.vCfg.data);
        if(this.vCfg.placement=='top'){
            let pos = this.$head.outerHeight()+1;
            this.$main.css("bottom",pos+"px");
        }
        this.$main.show();
        this.renderStatus("add","active");
        //去掉重复注册
        $(document).unbind(this.vClickId);
        $(document).on(this.vClickId,this.evOff.bind(this));
    };

    evClear(e){
        this.vSelect=[];
        this.renderHead();
        this.$main.hide();
        if(this.vBindEvent){
            if((this.vCfg.valueType||'code') =='code')
                this.vBindEvent('')
            else
                this.vBindEvent(this.vSelect);
        }

    };

    evOk(e){
        this.$input[0].focus();
        this.$main.hide();

    };

    evRootClick(e){
        this.vTmpEvent.timeStamp = e.timeStamp;
        this.vTmpEvent.target =e .target;
    };

    evOff(e){
        if((e.type=='keydown' && (this.$main.is(':hidden') || document.activeElement.getAttribute('type')=='ok') ||
        (e.type=='click' && (this.vTmpEvent.timeStamp !=e.timeStamp || this.vTmpEvent.target !=e.target)))){
            this.$main.hide();
            this.renderStatus('remove','active');
            this.verify();
            $(document).unbind(this.vClickId);
        }
    }

    evKeydown(e){
        let keynum = window.event ? e.keyCode : e.which;
        switch(keynum){
            //enter
            case 13:
                break;
            //tab 失去焦点
            case 9:
                this.evOff.bind(this)(e);
                break;
            // esc
            case 27:
                this.$main.hide();
                break;
        }
    }
    /*click  事件处理 区块 结束*/


    setBindEvent(event){
        this.vBindEvent = event;
    };

    setValue(value){
        this.initValue(value);
    };

    setData(data){
        this.vCfg.data =data;
    }

    verify() {
        let result = true;
        if(this.vCfg.mandatory ){
            if(this.vSelect.length<1){
                this.renderStatus("remove",'valid');
                this.renderStatus("add","invalid");
                result =false
            }else {
                this.renderStatus("remove",'invalid');
                this.renderStatus("add","valid");
            }
        }
        return result;
    }

    getSelect(){
        return this.vSelect;
    }

}